from flask_login import login_user
from routes import db
from models.user_model import User, RegulationData
from sqlalchemy.exc import IntegrityError
import bcrypt

class UserService:
    def register_user(self, username, password, email):
        try:
            user = User(username=username, password=password,email=email)
            # user.set_password(password)
            db.session.add(user)
            db.session.commit()
            return user
        except IntegrityError:
            db.session.rollback()
            raise ValueError("Username or email already exists")

    def authenticate_user(self, username, password):
        user = User.query.filter_by(username=username).first()
        if not user:
            print("User not found")
            return None
        # print(user.password_hash, "User password_hash:")
        # print(password, "login password:")
        if bcrypt.checkpw(password.encode(), user.password_hash.encode()):
            return user
        return None


    def change_password(self, user, old_password, new_password):
        if user.password_hash == old_password:
            user.password_hash = new_password
            try:
                db.session.commit()
                return True
            except IntegrityError:
                db.session.rollback()
                raise ValueError("Password change failed")
        return False


    # def do_login(self, username: str, password: str) -> bool:
    #     attempted_user = User.query.filter_by(username=username).first()
    #     print("User ID:", attempted_user.id)
    #     print("Username:", attempted_user.username)
    #     print("password:", attempted_user.password)
    #     if attempted_user and attempted_user.check_password_correction(
    #             attempted_password=password
    #     ):
    #         login_user(attempted_user)
    #         return True
    #     return False

    # 发送明文到后端（HTTPS 加密传输） 后端使用 bcrypt 等算法加密
    def do_login(self, username: str, password: str) -> bool:
        user = User.query.filter_by(username=username).first()
        if user and bcrypt.checkpw(password.encode(), user.password_hash.encode()):
            login_user(user)
            return True
        return False


class RegulationDataService:
    def add_regulation_service(self, data):
        try:
            regulation_service = RegulationData(**data)
            db.session.add(regulation_service)
            db.session.commit()
            return regulation_service
        except IntegrityError:
            db.session.rollback()
            raise ValueError("Data violates unique constraints")

    def update_regulation_service(self, id, data):
        try:
            regulation_service = RegulationData.query.get(id)
            if regulation_service:
                for key, value in data.items():
                    setattr(regulation_service, key, value)
                db.session.commit()
                return regulation_service
            else:
                raise ValueError("Regulation Service not found")
        except IntegrityError:
            db.session.rollback()
            raise ValueError("Data violates unique constraints")

    def delete_regulation_service(self, id):
        try:
            regulation_service = RegulationData.query.get(id)
            if regulation_service:
                db.session.delete(regulation_service)
                db.session.commit()
                return True
            else:
                raise ValueError("Regulation Service not found")
        except IntegrityError:
            db.session.rollback()
            raise ValueError("Deletion failed")

    def get_regulation_service(self, id):
        regulation_service = RegulationData.query.get(id)
        if not regulation_service:
            raise ValueError("Regulation Service not found")
        return regulation_service

    def get_all_regulation_services(self):
        return RegulationData.query.all()

    def get_regulation_service_by_fields(self, year, gep_city, gep_district, gep_town):
        from models.user_model import RegulationData
        record = RegulationData.query.filter_by(
            year=year,
            gepCity=gep_city,
            gepDistrict=gep_district,
            gepTown=gep_town
        ).first()
        return record

    """
    **{k: v for k, v in data.items() if k not in ['year', 'gepCity', 'gepDistrict', 'gepTown']}
    这段代码的作用是：
        遍历 data 字典；
        跳过 year, gepCity, gepDistrict, gepTown 这些已经在构造函数中设置的字段；
        将其余字段自动赋值给新的 RegulationData 实例。
    """
    def update_regulation_service_by_fields(self, year, gep_city, gep_district, gep_town, data):
        # 1. 查询是否存在该记录
        record = self.get_regulation_service_by_fields(year, gep_city, gep_district, gep_town)

        if not record:
            # 2. 如果不存在，则创建新记录，并从 data 中提取所有合法字段
            record = RegulationData(
                year=year,
                gepCity=gep_city,
                gepDistrict=gep_district,
                gepTown=gep_town,
                **{k: v for k, v in data.items() if k not in ['year', 'gepCity', 'gepDistrict', 'gepTown']}
            )
        else:
            # 3. 如果存在，则仅更新传入的字段（避免覆盖已有数据）
            for key, value in data.items():
                setattr(record, key, value)

        # 4. 提交更改或新增
        db.session.add(record)
        db.session.commit()
        return record

    def delete_regulation_service_by_fields(self, year, gep_city, gep_district, gep_town):
        record = self.get_regulation_service_by_fields(year, gep_city, gep_district, gep_town)
        if not record:
            return False
        db.session.delete(record)
        db.session.commit()
        return True
